import { runIntervally } from '@/utils/functions/inInterval';
import { guardObj } from '@/utils/functions/safeAccesss';
import { Logger } from '@/utils/logger';
import { BaseColonyModule } from '../moduleBase';
import { useContainer, useDrop, useLink } from './role';

declare global {
    interface ColonyMemory {
        /**
         * Creep 采集绑定，id <---> harvester 名字数组
         */
        harvestBind?: {
            [id: Id<Source>]: string[];
        }
    }
    interface CreepMemory {
        harvestMode?: 'drop' | 'container' | 'link';
    }
}

const getHarvestPos = (source: Source) => {
    let num = 0;
    for (const dx of [-1, 0, 1]) {
        for (const dy of [-1, 0, 1]) {
            const pos = new RoomPosition(source.pos.x + dx, source.pos.y + dy, source.pos.roomName);
            num += pos.isPassible() ? 1 : 0;
        }
    }
    return num;
}

/**
 * **采集控制模块**
 * 
 * 这个模块负责采集房间里的 Source 和 Mineral。`manage` 方法每
 * tick 都需要调用。
 */
export class HarvestModule extends BaseColonyModule {

    stopHarvestSource() {
        // 把每一个 harvester 的 temporary 设置为 true，这样就不会继续产爬了
        this.colony.creepsByRole[CreepRole.harvester].forEach(harvester => {
            harvester.memory.temporary = true;
            harvester.say('✋no resp');
        });
    }

    /**
     * 执行具体任务，每 tick 都需要调用
     */
    handle() {
        this.memory.harvestBind ??= {};

        this.runCreeps(CreepRole.harvester, harvester => {
            const { memory } = harvester;

            const source = Game.getObjectById(memory.target);
            if (source && !('energy' in source)) {
                // 不是 Source，警告后退出
                Logger.warn(`${harvester.mark} 的 target id=${source.id} 有误`, this.name);
                return;
            }
            if (!memory.harvestMode) {
                // 没有被分配模式，就判断周围环境来确定模式
                this.determineHarvestMode(harvester);
            }

            // 绑定到内存
            if (memory.onBorn) {
                if (!this.memory.harvestBind[memory.target]) {
                    this.memory.harvestBind[memory.target] = [harvester.name];
                }
                else {
                    this.memory.harvestBind[memory.target].push(harvester.name);
                }
            }

            // 根据模式运行
            if (memory.harvestMode === 'drop') {
                useDrop(harvester);
            }
            else if (memory.harvestMode === 'container') {
                useContainer(harvester);
            }
            else if (memory.harvestMode === 'link') {
                useLink(harvester);
            }
            else {
                Logger.warn(`${harvester.mark} 没有可用的 harvestMode`, this.name);
            }
        }, { disableAuto: true });
    }

    private determineHarvestMode(harvester: Creep) {
        const { memory } = harvester;
        const source = Game.getObjectById(memory.target);

        const link = this.colony.capital
            .getLinks()
            .find(link => link.pos.inRangeTo(source, 2));
        if (link) {
            memory.harvestMode = 'link';
            harvester.say('mode=link');
            return;
        }

        const container = this.colony.capital
            .getContainers()
            .find(cont => cont.pos.inRangeTo(source, 2));
        if (container) {
            memory.harvestMode = 'container';
            harvester.say('mode=cont');
            return;
        }

        memory.harvestMode = 'drop';
        harvester.say('mode=drop');
        return;
    }

}
